using System;
using System.Web;

namespace MimeCloud.WPF.Presentation
{
    public class Singleton<T> where T : class, new()
    {
        #region AppScoped
        private static T appScopedInstance = null;
        /// <summary>
        /// Gets a singleton reference to the type scoped to the AppDomain.
        /// </summary>
        public static T AppScoped
        {
            get 
            {
                if (appScopedInstance == null)
                    appScopedInstance = new T();
                return appScopedInstance; 
            }
        }
        #endregion AppScoped

        #region RequestScoped
        /// <summary>
        /// Gets a singleton reference to the type scoped to the HttpContext.
        /// </summary>
        public static T RequestScoped
        {
            get
            {
                T oCheck = null;
                string key = GetKeyForType(typeof (T));
                if (HttpContext.Current != null)
                {
                    oCheck = HttpContext.Current.Items[key] as T;

                    if (oCheck == null)
                    {
                        oCheck = new T();
                        HttpContext.Current.Items[key] = oCheck;
                    }
                }

                return oCheck;
            }
            set
            {
                T val = value;
                string key = GetKeyForType(typeof (T));
                HttpContext.Current.Items[key] = val;
            }
        }

        /// <summary>
        /// Gets a string key based on a type.
        /// </summary>
        /// <param name="typeOfT">The type.</param>
        /// <returns></returns>
        private static string GetKeyForType(Type typeOfT)
        {
            return typeOfT.FullName.GetHashCode().ToString();
        }
        #endregion RequestScoped

        /// <summary>
        /// Returns a singleton object scoped in either the HttpRequest if the user is in an HttpContext or AppScoped if there is no HttpContext
        /// </summary>
        public static T UserContextScoped
        {
            get
            {
                return HttpContext.Current!=null ? RequestScoped : AppScoped;
            }
        }
    }
}